package freedom.platform.service.impl;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import freedom.platform.dao.UserDao;
import freedom.platform.enums.YesOrNo;
import freedom.platform.model.ResourceItem;
import freedom.platform.model.Role;
import freedom.platform.model.User;
import freedom.platform.service.UserDetailsService;

/**
 * @author charlie
 *
 */
@Service("userDetailsService")
public class UserDetailsServiceImpl implements UserDetailsService {

    @Autowired
    private UserDao userDao;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userDao.findByUsername(username);
        if (user == null)
            throw new UsernameNotFoundException("UsernameNotFound");

        Collection<GrantedAuthority> authorities = getPermissions(user);
        UserDetails userDetails =
            new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(),
                YesOrNo.NO == user.getDeleteFlag(), true, true, YesOrNo.NO == user.getLockFlag(), authorities);
        return userDetails;
    }

    private Collection<GrantedAuthority> getPermissions(User user) {
        Set<Long> ids = new HashSet<Long>();

        for (Role role : user.getRoles()) {
            Collection<ResourceItem> resourceItems = role.getResourceItems();
            for (ResourceItem resourceItem : resourceItems) {
                if (StringUtils.hasText(resourceItem.getUrl()))
                    ids.add(resourceItem.getId());
            }
        }

        Collection<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
        for (Long id : ids) {
            SimpleGrantedAuthority authority = new SimpleGrantedAuthority(String.valueOf(id));
            authorities.add(authority);
        }
        return authorities;
    }

}
